package cc.cc4414.cc02.core.aspect;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import cc.cc4414.cc02.core.result.ResultException;
import cc.cc4414.cc02.core.result.ResultVO;
import cc.cc4414.cc02.core.util.IpUtils;
import cc.cc4414.cc02.core.util.JsonUtils;
import cc.cc4414.cc02.system.entity.OperationLog;
import cc.cc4414.cc02.system.entity.User;
import cc.cc4414.cc02.system.repository.OperationLogRepository;
import lombok.extern.slf4j.Slf4j;

/**
 * 使用aop记录操作日志
 * 
 * @author cc 2018年8月1日
 */
@Aspect
@Component
@Slf4j
public class OperationLogAspect {

	@Autowired
	private OperationLogRepository operationLogRepository;

	@Around("@annotation(logAspect)")
	public Object OperationLogAround(ProceedingJoinPoint pjp, LogAspect logAspect) throws Throwable {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getRequest();
		OperationLog operationLog = new OperationLog();
		operationLog.setDescription(logAspect.value());
		operationLog.setMethod(request.getMethod());
		operationLog.setUrl(request.getRequestURI());
		operationLog.setIp(IpUtils.getIp(request));
		operationLog.setTime(new Date());
		operationLog.setParam(JsonUtils.format(pjp.getArgs()));
		try {
			User user = getUser();
			operationLog.setUserId(user.getId());
			operationLog.setNickname(user.getNickname());
		} catch (Exception e) {
			log.warn("用户未登录");
		}
		Object result = null;
		try {
			result = pjp.proceed();
		} catch (ResultException e) {
			result = new ResultVO<>(e.getCode(), e.getMessage());
			throw e;
		} catch (Exception e) {
			result = e.getMessage();
			throw e;
		} finally {
			operationLog.setResult(JsonUtils.format(result));
			operationLogRepository.save(operationLog);
		}
		return result;
	}

	/**
	 * 获取当前登录用户信息
	 * 
	 * @return 当前用户
	 */
	private User getUser() {
		User user = new User();
		UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		BeanUtils.copyProperties(userDetails, user);
		return user;
	}
}
